home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume4 / unaxcess / part2 < prev    next >
Encoding:
Internet Message Format  |  1986-11-30  |  49.7 KB

  1. Subject: UNaXcess (2 of 3)
  2. Newsgroups: mod.sources
  3. Approved: jpn@panda.UUCP
  4.  
  5. Mod.sources:  Volume 4, Issue 66
  6. Submitted by: decvax!cwruecmp!ncoast!allbery
  7.  
  8. #! /bin/sh
  9. # This is a shell archive, meaning:
  10. # 1. Remove everything above the #! /bin/sh line.
  11. # 2. Save the resulting text in a file.
  12. # 3. Execute the file with /bin/sh (not csh) to create the files:
  13. #    bull.c
  14. #    conf.c
  15. #    date.c
  16. #    dir.c
  17. #    msg.c
  18. #    param.c
  19. #    sys.c
  20. # This archive created: Sat Apr 12 10:02:51 1986
  21. export PATH; PATH=/bin:$PATH
  22. echo shar: extracting "'bull.c'" '(1154 characters)'
  23. if test -f 'bull.c'
  24. then
  25.     echo shar: will not over-write existing file "'bull.c'"
  26. else
  27. cat << \SHAR_EOF > 'bull.c'
  28. /*
  29.  * %W% %E% %U% ncoast!bsa %Z%
  30.  * %Z% Copyright (C) 1986 by Brandon S. Allbery, All Rights Reserved %Z%
  31.  */
  32.  
  33. #ifndef lint
  34. static char _SccsId[] = "%W% %E% %U% ncoast!bsa %Z%";
  35. static char _CopyRt[] = "%Z% Copyright (C) 1985 by Brandon S. Allbery %Z%";
  36. #endif  lint
  37.  
  38. #include "ua.h"
  39.  
  40. bulletin(s)
  41.     char *s;
  42.     {
  43.     short mcnt, himotd;
  44.     char tmps[256];
  45.     FILE *fp;
  46.  
  47.     if (user.u_access == A_MKUSER)
  48.         return;
  49.     sprintf(tmps, "%s/himotd", MOTD);
  50.     if ((fp = fopen(tmps, "r")) == NULL)
  51.     {
  52.     log("Error %d opening %s", errno, tmps);
  53.     panic("himotd");
  54.     }
  55.     fgets(tmps, 32, fp);
  56.     fclose(fp);
  57.     himotd = atoi(tmps);
  58.     for (mcnt = (strcmp(user.u_name, "guest") == 0? 0: user.u_nbull + 1); mcnt <= himotd; mcnt++)
  59.     {
  60.     sprintf(tmps, "%s/%d", MOTD, mcnt);
  61.     if (!readmotd(tmps, mcnt))
  62.         break;
  63.     }
  64.     }
  65.  
  66. readmotd(motd, mnum)
  67.     char *motd;
  68.     short mnum;
  69.     {
  70.     char line[256];
  71.  
  72.     printf("Bulletin #%d:\n", mnum);
  73.     cat(motd);
  74.     printf("\nContinue or Stop (C)? ");
  75.     if (!isatty(0) || nopause)
  76.     {
  77.     putchar('\n');
  78.     line[0] = '\0';
  79.     }
  80.     else
  81.     gets(line);
  82.     log("C/S? %s", line);
  83.     return ToLower(line[0]) != 's';
  84.     }
  85. SHAR_EOF
  86. if test 1154 -ne "`wc -c < 'bull.c'`"
  87. then
  88.     echo shar: error transmitting "'bull.c'" '(should have been 1154 characters)'
  89. fi
  90. fi
  91. echo shar: extracting "'conf.c'" '(13406 characters)'
  92. if test -f 'conf.c'
  93. then
  94.     echo shar: will not over-write existing file "'conf.c'"
  95. else
  96. cat << \SHAR_EOF > 'conf.c'
  97. /*
  98.  * %W% %E% %U% ncoast!bsa %Z%
  99.  * %Z% Copyright (C) 1986 by Brandon S. Allbery, All Rights Reserved %Z%
  100.  */
  101.  
  102. #ifndef lint
  103. static char _SccsId[] = "%W% %E% %U% ncoast!bsa %Z%";
  104. static char _CopyRt[] = "%Z% Copyright (C) 1985 by Brandon S. Allbery %Z%";
  105. #endif  lint
  106.  
  107. #include "ua.h"
  108.  
  109. char conference[33];
  110.  
  111. confidx()
  112.     {
  113.     FILE *ifd;
  114.     short icnt, himsg;
  115.     char line[256];
  116.     DIR *dp;
  117.     struct direct *dfd;
  118.  
  119.     icnt = 0;
  120.     puts("\n\"!\" after a conference name indicates an unsubscribed-to conference.\n\nConference                        HiMsg Conference                        HiMsg");
  121.     if ((dp = opendir(MSGBASE)) == NULL)
  122.     {
  123.     log("Error %d opening dir %s/", errno, MSGBASE);
  124.     panic("msgdir");
  125.     }
  126.     while ((dfd = readdir(dp)) != NULL)
  127.     {
  128.     if (dfd->d_name[0] == '.')
  129.         continue;
  130.     sprintf(line, "%s/%s/himsg", MSGBASE, dfd->d_name);
  131.     if ((ifd = fopen(line, "r")) == NULL)
  132.         {
  133.         log("No himsg in conference %s", dfd->d_name);
  134.         continue;
  135.         }
  136.     fgets(line, 32, ifd);
  137.     himsg = atoi(line);
  138.     printf("%-32.32s%c %-5d", dfd->d_name, (isunsub(dfd->d_name)? '!': ':'), himsg);
  139.     fclose(ifd);
  140.     if (user.u_llen < 80 || !(++icnt % 2))
  141.         putchar('\n');
  142.     else if (!(icnt % 2))
  143.         putchar('|');
  144.     }
  145.     closedir(dp);
  146.     puts("\n");
  147.     return 1;
  148.     }
  149.  
  150. join(c)
  151.     char *c;
  152.     {
  153.     char line[256], *p;
  154.  
  155.     p = c - 1;
  156.     while (*++p != '\0')
  157.     if (*p == ' ')
  158.         if (verify(++p))
  159.         {
  160.         strcpy(conference, p);
  161.         return 1;
  162.         }
  163.     do
  164.     {
  165.     printf("Enter conference: ");
  166.     gets(line);
  167.     log("Enter conference: %s", line);
  168.     if (line[0] == '\0')
  169.         return 1;
  170.     }
  171.     while (!verify(line));
  172.     strcpy(conference, line);
  173.     log("Current conference is %s", conference);
  174.     return 1;
  175.     }
  176.  
  177. verify(conf)
  178.     char *conf;
  179.     {
  180.     char *cp, line[256];
  181.  
  182.     for (cp = conf; *cp != 0; cp++)
  183.     {
  184.     if (!isprint(*cp))
  185.         return 0;
  186.     else if (*cp == '/' || *cp == '!' || *cp == ':')
  187.         *cp = '.';
  188.     else
  189.         *cp = ToLower(*cp);
  190.     }
  191.     if (cp - conf > CONFSIZE)
  192.     conf[CONFSIZE] = '\0';
  193.     sprintf(line, "%s/%s", MSGBASE, conf);
  194.     if (chdir(line) == -1)
  195.     {
  196.     if (errno != ENOENT)
  197.         {
  198.         log("Error %d accessing dir %s/", errno, line);
  199.         return 0;
  200.         }
  201.     else
  202.         return newconf(conf);
  203.     }
  204.     chdir("../..");
  205.     if (isunsub(conf)) {
  206.         printf("You are unsubscribed from this conference.  Rejoin (N)? ");
  207.         gets(line);
  208.         log("Unsubscribed.  Resubscribe? %s", line);
  209.         if (ToLower(line[0]) == 'y')
  210.             resubscribe(conf);
  211.         else
  212.             return 0;
  213.     }
  214.     if (parms.ua_xrc && conf[0] == 'x' && conf[1] == '-')
  215.     {
  216.     printf("This is a Restricted Access (X-RATED) conference.  The material within\n may be unsuitable for, or unacceptable to, some users of UNaXcess.\n\nDo you still wish to join this conference (N)? ");
  217.     gets(line);
  218.     log("Restricted.  Join? %s", line);
  219.     return (ToLower(line[0]) == 'y');
  220.     }
  221.     return 1;
  222.     }
  223.  
  224. killmsg(n)
  225.     char *n;
  226.     {
  227.     short mnum, flag;
  228.     char line[256], *p;
  229.  
  230.     if (user.u_access == A_GUEST)
  231.     {
  232.     puts("You aren't authorized for this function.");
  233.     log("Security violation:  KILL by a GUEST");
  234.     return 1;
  235.     }
  236.     flag = 0;
  237.     for (p = n; *p != '\0'; p++)
  238.     if (*p == ' ')
  239.         {
  240.         if ((mnum = atoi(++p)) < 1)
  241.         break;
  242.         dokill(mnum);
  243.         flag++;
  244.         }
  245.     if (flag)
  246.     return 1;
  247.     printf("Enter message number to kill: ");
  248.     gets(line);
  249.     if (line[0] == '\0')
  250.     return 1;
  251.     if ((mnum = atoi(line)) < 1)
  252.     {
  253.     puts("Bad message number.");
  254.     log("Bad message number: %s", line);
  255.     return 1;
  256.     }
  257.     dokill(mnum);
  258.     return 1;
  259.     }
  260.  
  261. dokill(msg)
  262.     short msg;
  263.     {
  264.     char mfile[256];
  265.  
  266.     sprintf(mfile, "%s/%s/%d", MSGBASE, conference, msg);
  267.     if (user.u_access != A_WITNESS && strcmp(getowner(mfile), user.u_name) != 0)
  268.     {
  269.     puts("Sorry, you don't own that message.");
  270.     log("Security violation:  KILL by non-owner");
  271.     return;
  272.     }
  273.     if (unlink(mfile) < 0)
  274.     {
  275.     printf("No such message: %d", msg);
  276.     log("Error %d unlinking %s", errno, mfile);
  277.     return;
  278.     }
  279.     log("Deleted %s:%d", conference, msg);
  280.     }
  281.  
  282. char *getowner(file)
  283.     char *file;
  284.     {
  285.     FILE *f;
  286.     char line[1024], *p;
  287.     static char owner[256];
  288.  
  289.     strcpy(owner, parms.ua_sysop);
  290.     if ((f = fopen(file, "r")) == NULL)
  291.     return owner;
  292.     while (fgets(line, 1024, f) != NULL)
  293.     if (line[0] == '\n')
  294.         break;
  295.     else if (strncmp(line, "From: ", 6) == 0)
  296.         {
  297.         strcpy(owner, &line[6]);
  298.         break;
  299.         }
  300.     fclose(f);
  301.     for (p = owner; *p != '\0'; p++)
  302.     *p = ToLower(*p);
  303.     return owner;
  304.     }
  305.  
  306. newconf(conf)
  307.     char *conf;
  308.     {
  309.     char line[256];
  310.     FILE *f;
  311.  
  312.     if (user.u_access == A_GUEST)
  313.     {
  314.     log("Security violation:  attempted MKCONF by guest");
  315.     puts("Sorry, there is no such conference.");
  316.     return 0;
  317.     }
  318.     printf("There is no conference by that name.  Do you want to create it (N)? ");
  319.     gets(line);
  320.     log("Nonexistent.  Create? %s", line);
  321.     if (ToLower(line[0]) != 'y')
  322.     return 0;
  323.     if (parms.ua_xrc && conf[0] == 'x' && conf[1] == '-')
  324.     {
  325.     printf("Conferences beginning with \"x-\" are designated as Restricted Access (X-RATED)\nconferences under UNaXcess, and will often carry information unsuitable for some\n");
  326.     printf("users or unacceptable to some users.  If you do not wish to create such a\nconference, answer NO to the next question and choose a conference name not\n");
  327.     printf("beginning with the characters \"x-\".\n\nDo you wish to create an X-RATED conference (N)? ");
  328.     gets(line);
  329.     log("Restricted.  Create? %s", line);
  330.     if (ToLower(line[0]) != 'y')
  331.         return 0;
  332.     }
  333.     if (parms.ua_roc && conf[0] == 'r' && conf[1] == '-')
  334.     if (user.u_access != A_WITNESS)
  335.         {
  336.         puts("Only Fairwitnesses can make READ-ONLY conferences.");
  337.         log("Attempted mk of RO conf by non-FW");
  338.         return 0;
  339.         }
  340.     else
  341.         {
  342.         puts("This conference will be READ-ONLY, except to Fairwitnesses.\nIf you want anyone to be able to add to it, answer NO and use a name not\nbeginning with \"R-\".");
  343.         printf("\nDo you want to make this READ-ONLY conference (N)? ");
  344.         gets(line);
  345.         log("Read-only.  Create? %s", line);
  346.         if (ToLower(line[0]) != 'y')
  347.         return 0;
  348.         }
  349.     sprintf(line, "exec mkconf %s/%s %d", MSGBASE, conf, geteuid());
  350.     if (system(line) != 0)
  351.     {
  352.     log("Mkconf of %s failed.", conf);
  353.     puts("Hmmm... guess you aren't allowed.");
  354.     return 0;
  355.     }
  356.     log("New conference: %s", conf);
  357.     sprintf(line, "%s/%s/himsg", MSGBASE, conf);
  358.     if ((f = fopen(line, "w")) == NULL)
  359.     {
  360.     log("Error %d opening %s", line);
  361.     puts("Can't create high message file.  Strange...");
  362.     return 0;
  363.     }
  364.     fputs("0", f);
  365.     fclose(f);
  366.     puts("You will now be placed in the message editor to make a message describing\nthis conferemnce.  It will be addressed to, and readable by, all users.");
  367.     mkmsg("All", "This conference", conf, 0);
  368.     return 1;
  369.     }
  370.  
  371. isprivate(msg)
  372.     char *msg;
  373.     {
  374.     FILE *fp;
  375.     char line[1024], to[1024], from[1024];
  376.     short pflag;
  377.  
  378.     if (user.u_access == A_WITNESS)
  379.     return 0;
  380.     if ((fp = fopen(msg, "r")) == NULL)
  381.     return 0;
  382.     strcpy(to, "All");
  383.     pflag = 0;
  384.     while (fgets(line, 1024, fp) != NULL)
  385.     {
  386.     if (line[0] == '\n')
  387.         break;
  388.     else if (strncmp(line, "To: ", 4) == 0)
  389.         strcpy(to, &line[4]);
  390.     else if (strncmp(line, "From: ", 6) == 0)
  391.         strcpy(from, &line[6]);
  392.     else if (strncmp(line, "Subject (Private): ", 19) == 0)
  393.         pflag = 1;
  394.     }
  395.     fclose(fp);
  396.     if (pflag && strcmp(user.u_name, to) == 0)
  397.     return 0;
  398.     else if (pflag && strcmp(user.u_name, from) == 0)
  399.     return 0;
  400.     else if (pflag)
  401.     {
  402.     log("Message %s is private.", msg);
  403.     return 1;
  404.     }
  405.     else
  406.     return 0;
  407.     }
  408.  
  409. isunsub(conf)
  410. char *conf; {
  411.     struct _himsg *hip;
  412.  
  413.     for (hip = hicnts; hip != NULL; hip = hip->hi_next)
  414.         if (strcmp(hip->hi_conf, conf) == 0)
  415.             break;
  416.     return (hip != NULL && hip->hi_uns == HI_UNSUB);
  417. }
  418.  
  419. unsubscribe(conf)
  420. char *conf; {
  421.     struct _himsg *hip, *workp;
  422.     char line[512];
  423.     
  424.     if (s_cmp(conf, "general") == 0) {
  425.         puts("Can't unsubscribe the general conference.");
  426.         log("Attempted to unsubscribe to general.");
  427.         return;
  428.     }
  429.     if (s_cmp(conf, user.u_lconf) == 0) {
  430.         printf("Unsubscribe to login conference (N)? ");
  431.         gets(line);
  432.         log("Unsub login conf? %s", line);
  433.         if (ToLower(line[0]) != 'y')
  434.             return;
  435.         strcpy(user.u_lconf, "general");
  436.     }
  437.     for (hip = hicnts; hip != NULL; hip = hip->hi_next)
  438.         if (strcmp(hip->hi_conf, conf) == 0)
  439.             break;
  440.     if (hip != NULL)
  441.         hip->hi_uns = HI_UNSUB;
  442.     else {
  443.     if ((workp = (struct _himsg *) calloc((unsigned) 1, sizeof (struct _himsg))) == NULL)
  444.         {
  445.         log("Error %d allocating _himsg for %s", errno, conf);
  446.         panic("alloc");
  447.         }
  448.     strcpy(workp->hi_conf, conf);
  449.     workp->hi_num = 0;
  450.     workp->hi_next = hicnts;
  451.     hicnts = workp;
  452.     workp->hi_uns = HI_UNSUB;
  453.     }
  454.     log("Unsubscribed to %s", conf);
  455.     printf("Unsubscribed to conference %s.\n", conf);
  456. }
  457.  
  458. resubscribe(conf)
  459. char *conf; {
  460.     struct _himsg *hip, *workp;
  461.     
  462.     for (hip = hicnts; hip != NULL; hip = hip->hi_next)
  463.         if (strcmp(hip->hi_conf, conf) == 0)
  464.             break;
  465.     if (hip != NULL)
  466.         hip->hi_uns = HI_SUBSCR;
  467.     else {
  468.     if ((workp = (struct _himsg *) calloc((unsigned) 1, sizeof (struct _himsg))) == NULL)
  469.         {
  470.         log("Error %d allocating _himsg for %s", errno, conf);
  471.         panic("alloc");
  472.         }
  473.     strcpy(workp->hi_conf, conf);
  474.     workp->hi_num = 0;
  475.     workp->hi_next = hicnts;
  476.     hicnts = workp;
  477.     workp->hi_uns = HI_SUBSCR;
  478.     }
  479.     log("Resubscribed to %s", conf);
  480.     printf("Resubscribed to conference %s.\n", conf);
  481. }
  482.  
  483. unsub(c)
  484. char *c; {
  485.     char line[256], *p;
  486.  
  487.     p = c - 1;
  488.     while (*++p != '\0')
  489.     if (*p == ' ')
  490.         if (isconf(++p))
  491.         {
  492.         unsubscribe(p);
  493.         return 1;
  494.         }
  495.     for (;;) {
  496.     printf("Unsubscribe to which conference (%s) [NONE to abort]: ", conference);
  497.     gets(line);
  498.     log("Unsub conference: %s", line);
  499.     if (line[0] == '\0') {
  500.         unsubscribe(conference);
  501.         return 1;
  502.     }
  503.     if (s_cmp(line, "none") == 0)
  504.         return 1;
  505.     if (isconf(line)) {
  506.         unsubscribe(line);
  507.         return 1;
  508.     }
  509.     }
  510. }
  511.  
  512. isconf(conf)
  513. char *conf; {
  514.     char *cp, line[256];
  515.  
  516.     for (cp = conf; *cp != 0; cp++) {
  517.         if (!isprint(*cp))
  518.         return 0;
  519.     else if (*cp == '/' || *cp == '!' || *cp == ':')
  520.         *cp = '.';
  521.     else
  522.         *cp = ToLower(*cp);
  523.     }
  524.     if (cp - conf > CONFSIZE)
  525.     conf[CONFSIZE] = '\0';
  526.     sprintf(line, "%s/%s", MSGBASE, conf);
  527.     if (chdir(line) == -1)
  528.         return 0;
  529.     chdir("../..");
  530.     return 1;
  531. }
  532.  
  533. setlconf(conf)
  534. char *conf; {
  535.     char line[256], *p;
  536.  
  537.     if (s_cmp(user.u_name, "guest") == 0) {
  538.         log("Guest SET LOGIN CONF denied.");
  539.         puts("GUEST can't set a login conference.");
  540.         return 1;
  541.     }
  542.     p = conf - 1;
  543.     while (*++p != '\0')
  544.     if (*p == ' ')
  545.         if (isconf(++p)) {
  546.                 if (isunsub(p)) {
  547.                     puts("You're unsubscribed from it.  <J>oin it and resubscribe.");
  548.                     log("Unsubscribed -- login conf set aborted.");
  549.                     return 1;
  550.                 }
  551.         strcpy(user.u_lconf, p);
  552.         log("New login conference: %s", user.u_lconf);
  553.                 putuser(user.u_name, &user);
  554.         return 1;
  555.         }
  556.     do {
  557.     printf("Enter new login conference: ");
  558.     gets(line);
  559.     log("Login conference: %s", line);
  560.     if (line[0] == '\0')
  561.         return 1;
  562.     } while (!isconf(line));
  563.     if (isunsub(line)) {
  564.         puts("You're unsubscribed from it.  <J>oin it and resubscribe.");
  565.         log("Unsubscribed -- login conf set aborted.");
  566.         return 1;
  567.     }
  568.     strcpy(user.u_lconf, line);
  569.     log("New login conference: %s", user.u_lconf);
  570.     putuser(user.u_name, &user);
  571.     return 1;
  572. }
  573.  
  574. uisunsub(user, conf)
  575. char *user, *conf; {
  576.     struct _himsg *hip, *uhi;
  577.     char *cp;
  578.  
  579.     for (cp = user; *cp != '\0'; cp++)
  580.         *cp = ToLower(*cp);
  581.     if ((uhi = readhigh(user)) < 0) {
  582.         log("Couldn't read %s's userindex.", user);
  583.         return 0;
  584.     }
  585.     for (hip = uhi; hip != NULL; hip = hip->hi_next)
  586.         if (strcmp(hip->hi_conf, conf) == 0)
  587.             break;
  588.     cp = (hip != NULL && hip->hi_uns == HI_UNSUB? "!": ":");
  589.     for (hip = uhi->hi_next; uhi != NULL; uhi = hip)
  590.         free((char *) uhi);
  591.     return (*cp == '!');
  592. }
  593.  
  594. cleanhigh() {
  595.     struct _himsg *hip, *lastp;
  596.     DIR *conferences;
  597.     struct direct *conf;
  598.     
  599.     lastp = NULL;
  600.     puts("Checking for deleted conferences...");
  601.     for (hip = hicnts; hip != NULL; lastp = hip, hip = hip->hi_next) {
  602.         if (!isconf(hip->hi_conf)) {
  603.             printf("Conference \"%s\" was deleted since your last session.\n", hip->hi_conf);
  604.             if (lastp == NULL)
  605.                 hicnts = hip->hi_next;
  606.             else
  607.                 lastp->hi_next = hip->hi_next;
  608.             free((char *) hip);
  609.         }
  610.     }
  611.     puts("\nChecking for new conferences...");
  612.     if ((conferences = opendir(MSGBASE)) == NULL) {
  613.         log("Error %d opening dir %s/", errno, MSGBASE);
  614.         panic("msgdir");
  615.     }
  616.     while ((conf = readdir(conferences)) != NULL) {
  617.         if (strcmp(conf->d_name, ".") == 0)
  618.             continue;
  619.         if (strcmp(conf->d_name, "..") == 0)
  620.             continue;
  621.         for (hip = hicnts; hip != NULL; hip = hip->hi_next)
  622.             if (strcmp(hip->hi_conf, conf->d_name) == 0)
  623.                 break;
  624.         if (hip == NULL)
  625.             printf("Conference \"%s\" has been created since your last session.\n", conf->d_name);
  626.     }
  627.     closedir(conferences);
  628. }
  629. SHAR_EOF
  630. if test 13406 -ne "`wc -c < 'conf.c'`"
  631. then
  632.     echo shar: error transmitting "'conf.c'" '(should have been 13406 characters)'
  633. fi
  634. fi
  635. echo shar: extracting "'date.c'" '(1557 characters)'
  636. if test -f 'date.c'
  637. then
  638.     echo shar: will not over-write existing file "'date.c'"
  639. else
  640. cat << \SHAR_EOF > 'date.c'
  641. /*
  642.  * %W% %E% %U% ncoast!bsa %Z%
  643.  * %Z% Copyright (C) 1986 by Brandon S. Allbery, All Rights Reserved %Z%
  644.  */
  645.  
  646. #ifndef lint
  647. static char _SccsId[] = "%W% %E% %U% ncoast!bsa %Z%";
  648. static char _CopyRt[] = "%Z% Copyright (C) 1985 by Brandon S. Allbery %Z%";
  649. #endif  lint
  650.  
  651. #ifdef BSD
  652. #include <sys/time.h>
  653. #else
  654. #include <time.h>
  655. #endif BSD
  656.  
  657. static char *month[] =
  658.     {
  659.     "January",    "February",    "March",    "April",
  660.     "May",        "June",        "July",        "August",
  661.     "September",    "October",    "November",    "December"
  662.     };
  663.  
  664. static char *wkday[] =
  665.     {
  666.     "Sunday",    "Monday",    "Tuesday",    "Wednesday",
  667.     "Thursday",    "Friday",    "Saturday"
  668.     };
  669.  
  670. struct tm *localtime();
  671.  
  672. char *date()
  673.     {
  674.     long clock;
  675.     struct tm *ltbuf;
  676.     static char tbuf[18];
  677.  
  678.     time(&clock);
  679.     ltbuf = localtime(&clock);
  680.     sprintf(tbuf, "%02d/%02d/%02d %02d:%02d:%02d", ltbuf->tm_mon + 1, ltbuf->tm_mday, ltbuf->tm_year, ltbuf->tm_hour, ltbuf->tm_min, ltbuf->tm_sec);
  681.     return tbuf;
  682.     }
  683.  
  684. char *longdate()
  685.     {
  686.     long clock;
  687.     struct tm *ltbuf;
  688.     static char tbuf[80];
  689.     short hour;
  690.     char ampm;
  691.  
  692.     time(&clock);
  693.     ltbuf = localtime(&clock);
  694.     if (ltbuf->tm_hour == 0)
  695.     {
  696.     hour = 12;
  697.     ampm = 'A';
  698.     }
  699.     else if (ltbuf->tm_hour < 12)
  700.     {
  701.     hour = ltbuf->tm_hour;
  702.     ampm = 'A';
  703.     }
  704.     else if (ltbuf->tm_hour == 12)
  705.     {
  706.     hour = 12;
  707.     ampm = 'P';
  708.     }
  709.     else
  710.     {
  711.     hour = ltbuf->tm_hour - 12;
  712.     ampm = 'P';
  713.     }
  714.     sprintf(tbuf, "%s, %s %d, 19%02d - %d:%02d %cM", wkday[ltbuf->tm_wday], month[ltbuf->tm_mon], ltbuf->tm_mday, ltbuf->tm_year, hour, ltbuf->tm_min, ampm);
  715.     return tbuf;
  716.     }
  717. SHAR_EOF
  718. if test 1557 -ne "`wc -c < 'date.c'`"
  719. then
  720.     echo shar: error transmitting "'date.c'" '(should have been 1557 characters)'
  721. fi
  722. fi
  723. echo shar: extracting "'dir.c'" '(2625 characters)'
  724. if test -f 'dir.c'
  725. then
  726.     echo shar: will not over-write existing file "'dir.c'"
  727. else
  728. cat << \SHAR_EOF > 'dir.c'
  729. /*
  730.  *
  731.  *                N O T I C E
  732.  *
  733.  * This file is NOT a copyrighted part of the UNaXcess distribution.  These
  734.  * are directory-reading routines which are compatible with the Berkeley Unix
  735.  * (4.2BSD, 4.3BSD) strectory routines.  They come from the Usenet news
  736.  * distribution and are in the public domain.
  737.  *
  738.  * To get the best use of them:  install the file "dir.h" in /usr/include
  739.  * -- standard usage calls it "ndir.h", and make a random archive of dir.o and
  740.  * put it in /usr/lib/libndir.a .  It is then available with "-lndir".
  741.  *
  742.  * Bell System {III, V} sites, just make an archive -- it is only one file
  743.  * anyway.  Other sites will have to run ranlib on the archive to keep ld
  744.  * happy.
  745.  */
  746.  
  747. #include <sys/types.h>
  748. #include "dir.h"
  749.  
  750. #ifndef BSD
  751.  
  752. /*
  753.  * close a directory.
  754.  */
  755. closedir(dirp)
  756.         register DIR *dirp;
  757. {
  758.         close(dirp->dd_fd);
  759.         dirp->dd_fd = -1;
  760.         dirp->dd_loc = 0;
  761.         free(dirp);
  762. }
  763.  
  764.  
  765.  
  766. /*
  767.  * open a directory.
  768.  */
  769. DIR *
  770. opendir(name)
  771.         char *name;
  772. {
  773.         register DIR *dirp;
  774.         register int fd;
  775.  
  776.         if ((fd = open(name, 0)) == -1)
  777.                 return NULL;
  778.         if ((dirp = (DIR *)malloc(sizeof(DIR))) == NULL) {
  779.                 close (fd);
  780.                 return NULL;
  781.         }
  782.         dirp->dd_fd = fd;
  783.         dirp->dd_loc = 0;
  784.         return dirp;
  785. }
  786.  
  787.  
  788.  
  789. /*
  790.  * read an old style directory entry and present it as a new one
  791.  */
  792. #define ODIRSIZ 14
  793.  
  794. struct  olddirect {
  795.         ino_t   od_ino;
  796.         char    od_name[ODIRSIZ];
  797. };
  798.  
  799. /*
  800.  * get next entry in a directory.
  801.  */
  802. struct direct *
  803. readdir(dirp)
  804.         register DIR *dirp;
  805. {
  806.         register struct olddirect *dp;
  807.         static struct direct dir;
  808.  
  809.         for (;;) {
  810.                 if (dirp->dd_loc == 0) {
  811.                         dirp->dd_size = read(dirp->dd_fd, dirp->dd_buf, 
  812.                             DIRBLKSIZ);
  813.                         if (dirp->dd_size <= 0)
  814.                                 return NULL;
  815.                 }
  816.                 if (dirp->dd_loc >= dirp->dd_size) {
  817.                         dirp->dd_loc = 0;
  818.                         continue;
  819.                 }
  820.                 dp = (struct olddirect *)(dirp->dd_buf + dirp->dd_loc);
  821.                 dirp->dd_loc += sizeof(struct olddirect);
  822.                 if (dp->od_ino == 0)
  823.                         continue;
  824.                 dir.d_ino = dp->od_ino;
  825.                 strncpy(dir.d_name, dp->od_name, ODIRSIZ);
  826.                 dir.d_name[ODIRSIZ] = '\0'; /* insure null termination */
  827.                 dir.d_namlen = strlen(dir.d_name);
  828.                 dir.d_reclen = DIRBLKSIZ;
  829.                 return (&dir);
  830.         }
  831. }
  832.  
  833. #endif BSD
  834. SHAR_EOF
  835. if test 2625 -ne "`wc -c < 'dir.c'`"
  836. then
  837.     echo shar: error transmitting "'dir.c'" '(should have been 2625 characters)'
  838. fi
  839. fi
  840. echo shar: extracting "'msg.c'" '(16927 characters)'
  841. if test -f 'msg.c'
  842. then
  843.     echo shar: will not over-write existing file "'msg.c'"
  844. else
  845. cat << \SHAR_EOF > 'msg.c'
  846. /*
  847.  * %W% %E% %U% ncoast!bsa %Z%
  848.  * %Z% Copyright (C) 1986 by Brandon S. Allbery, All Rights Reserved %Z%
  849.  */
  850.  
  851. #ifndef lint
  852. static char _SccsId[] = "%W% %E% %U% ncoast!bsa %Z%";
  853. static char _CopyRt[] = "%Z% Copyright (C) 1985 by Brandon S. Allbery %Z%";
  854. #endif  lint
  855.  
  856. #include "ua.h"
  857.  
  858. selmsg(s, fn)
  859.     char *s;
  860.     int (*fn)();
  861.     {
  862.     char line[256], *p;
  863.     short lomsg, himsg;
  864.     FILE *f;
  865.  
  866.     sprintf(line, "%s/%s/himsg", MSGBASE, conference);
  867.     if ((f = fopen(line, "r")) == NULL)
  868.     {
  869.     log("Error %d opening %s", errno, line);
  870.     if (strcmp(conference, "general") == 0)
  871.         {
  872.         panic("conf");
  873.         }
  874.     puts("I can't find the high message file.  Moving back to general...");
  875.     strcpy(conference, "general");
  876.     return 1;
  877.     }
  878.     fgets(line, 32, f);
  879.     fclose(f);
  880.     himsg = atoi(line);
  881.     for (p = s; *p != 0; p++)
  882.     if (*p == ' ')
  883.         {
  884.         if (strcmp(++p, "new") == 0)
  885.         {
  886.         domsg(conference, 0, himsg, fn);
  887.         return 1;
  888.         }
  889.         else if ((lomsg = atoi(p)) < 1 || lomsg > himsg)
  890.         break;
  891.         else
  892.         {
  893.         domsg(conference, lomsg, lomsg, fn);
  894.         return 1;
  895.         }
  896.         }
  897.     printf("<F>orward, <R>everse, <I>ndividual, or <N>ew: ");
  898.     gets(line);
  899.     log("Mode: %s", line);
  900.     switch (line[0])
  901.     {
  902.     case 'F':
  903.     case 'f':
  904.         lomsg = 1;
  905.         break;
  906.     case 'R':
  907.     case 'r':
  908.         lomsg = himsg;
  909.         himsg = 1;
  910.         break;
  911.     case 'I':
  912.     case 'i':
  913.         printf("Enter message number: ");
  914.         gets(line);
  915.         log("Message: %s", line);
  916.         if ((lomsg = atoi(line)) < 1 || lomsg > himsg)
  917.         {
  918.         puts("No such message.");
  919.         log("No such message.");
  920.         return 1;
  921.         }
  922.         domsg(conference, lomsg, lomsg, fn);
  923.         return 1;
  924.     case 'N':
  925.     case 'n':
  926.         lomsg = 0;
  927.         break;
  928.     case '\0':
  929.         return 1;
  930.     default:
  931.         puts("What?");
  932.         log("Illegal search mode.");
  933.         return 1;
  934.     }
  935.     if (lomsg != 0)
  936.     {
  937.     printf("Starting message (%d): ", lomsg);
  938.     gets(line);
  939.     log("Start: %s", line);
  940.     if (line[0] != 0)
  941.         if (atoi(line) < 1 || (lomsg > 1 && atoi(line) > lomsg))
  942.         {
  943.         puts("Bad message number.");
  944.         log("Bad message number.");
  945.         return 1;
  946.         }
  947.         else
  948.         lomsg = atoi(line);
  949.     printf("Ending message (%d): ", himsg);
  950.     gets(line);
  951.     log("End: %s", line);
  952.     if (line[0] != 0)
  953.         if (atoi(line) < 1 || (himsg > 1 && atoi(line) > himsg))
  954.         {
  955.         puts("Bad message number.");
  956.         log("Bad message number.");
  957.         return 1;
  958.         }
  959.         else
  960.         himsg = atoi(line);
  961.     }
  962.     domsg(conference, lomsg, himsg, fn);
  963.     return 1;
  964.     }
  965.  
  966. readmsg(s)
  967.     char *s;
  968.     {
  969.     return selmsg(s, doread);
  970.     }
  971.  
  972. scanmsg(s)
  973.     char *s;
  974.     {
  975.     return selmsg(s, doscan);
  976.     }
  977.  
  978. doread(msg, conf, mnum)
  979.     char *msg, *conf;
  980.     short mnum;
  981.     {
  982.     char line[256];
  983.  
  984.     printf("\nMessage %d of %s:\n", mnum, conf);
  985.     if (isprivate(msg))
  986.     {
  987.     puts("This message is private.");
  988.     return 1;
  989.     }
  990.     cat(msg);
  991.  
  992. DR_Loop:
  993.     printf("\nContinue, Stop, Unsubscribe, or Reply (C): ");
  994.     if (!isatty(0) || nopause)
  995.     {
  996.     line[0] = '\0';
  997.     putchar('\n');
  998.     }
  999.     else
  1000.     gets(line);
  1001.     log("C/S/U/R: %s", line);
  1002.     switch (line[0])
  1003.     {
  1004.     case 'c':
  1005.     case 'C':
  1006.     case '\0':
  1007.         return 1;
  1008.         case 'U':
  1009.         case 'u':
  1010.             unsubscribe(conf);
  1011.             return 0;
  1012.     case 's':
  1013.     case 'S':
  1014.         return 0;
  1015.     case 'r':
  1016.     case 'R':
  1017.         reply(msg, conf);
  1018.         goto DR_Loop;
  1019.     default:
  1020.         puts("What?  Please enter one of C, S, U, or R.");
  1021.         goto DR_Loop;
  1022.     }
  1023.     }
  1024.  
  1025. msgok(file)
  1026.     char *file;
  1027.     {
  1028.     FILE *fp;
  1029.  
  1030.     if ((fp = fopen(file, "r")) == NULL)
  1031.     return 0;
  1032.     fclose(fp);
  1033.     return 1;
  1034.     }
  1035.  
  1036. doscan(msg, conf, mnum)
  1037. char *msg, *conf;
  1038. short mnum; {
  1039.     char line[1024];
  1040.     FILE *f;
  1041.     short dflag, fflag, tflag, sflag;
  1042.  
  1043.     if ((f = fopen(msg, "r")) == NULL) {
  1044.     puts("Cannot open file.");
  1045.     log("Error %d opening %s", errno, msg);
  1046.     return 1;
  1047.     }
  1048.     printf("\nMessage %d of %s: \n", mnum, conf);
  1049.     dflag = fflag = tflag = sflag = 0;
  1050.     if (isprivate(msg))
  1051.     puts("Message is private.");
  1052.     else {
  1053.     while (fgets(line, 1024, f) != NULL) {
  1054.         if (line[0] == '\n')
  1055.         break;
  1056.         if (!dflag && strncmp(line, "Date: ", 6) == 0) {
  1057.         printf("%s", line);
  1058.         dflag++;
  1059.         continue;
  1060.         }
  1061.         if (!fflag && strncmp(line, "From: ", 6) == 0) {
  1062.         printf("%s", line);
  1063.         fflag++;
  1064.         continue;
  1065.         }
  1066.         if (!tflag && strncmp(line, "To: ", 4) == 0) {
  1067.         printf("%s", line);
  1068.         tflag++;
  1069.         continue;
  1070.         }
  1071.         if (!sflag && strncmp(line, "Subject: ", 9) == 0) {
  1072.         printf("%s", line);
  1073.         sflag++;
  1074.         continue;
  1075.         }
  1076.         if (!sflag && strncmp(line, "Subject (Private): ", 19) == 0) {
  1077.         printf("%s", line);
  1078.         sflag++;
  1079.         continue;
  1080.         }
  1081.     }
  1082.         if (!tflag)
  1083.         puts("To: All");
  1084.     }
  1085.     fclose(f);
  1086.     puts("--------------------------------");
  1087.     if (mnum % 3 == 0)    /* kludged, but there isn't an easy fix without */
  1088.         if (!cont())    /* rewriting the I/O system. */
  1089.             longjmp(cmdloop, 1);    /* also a kludge... */
  1090.     return 1;
  1091.     }
  1092.  
  1093. domsg(conf, lomsg, himsg, fn)
  1094.     char *conf;
  1095.     short lomsg, himsg;
  1096.     int (*fn)();
  1097.     {
  1098.     short mcnt;
  1099.     char tmps[256];
  1100.     struct _himsg *ptr, *lastp;
  1101.  
  1102.     for (ptr = hicnts, lastp = NULL; ptr != NULL; lastp = ptr, ptr = ptr->hi_next)
  1103.     if (strcmp(conf, ptr->hi_conf) == 0)
  1104.         break;
  1105.     if (ptr == NULL)
  1106.     {
  1107.     if ((ptr = (struct _himsg *) calloc((unsigned) 1, sizeof (struct _himsg))) == NULL)
  1108.         {
  1109.         log("Error %d allocating _himsg for %s", errno, conf);
  1110.         panic("alloc");
  1111.         }
  1112.     ptr->hi_next = hicnts;
  1113.         hicnts = ptr;
  1114.         ptr->hi_uns = HI_SUBSCR;
  1115.     strcpy(ptr->hi_conf, conf);
  1116.     ptr->hi_num = 0;
  1117.     }
  1118.     if (lomsg == 0)            /* read new messages */
  1119.     for (mcnt = ptr->hi_num + 1; mcnt <= himsg; mcnt++)
  1120.         {
  1121.         sprintf(tmps, "%s/%s/%d", MSGBASE, conf, mcnt);
  1122.         if (msgok(tmps) <= 0)
  1123.         continue;
  1124.         if (!(*fn)(tmps, conf, mcnt))
  1125.         break;
  1126.         }
  1127.     else if (lomsg <= himsg)        /* forward or individual read */
  1128.     for (mcnt = lomsg; mcnt <= himsg; mcnt++)
  1129.         {
  1130.         sprintf(tmps, "%s/%s/%d", MSGBASE, conf, mcnt);
  1131.         if (msgok(tmps) <= 0)
  1132.         continue;
  1133.         if (!(*fn)(tmps, conf, mcnt))
  1134.         break;
  1135.         }
  1136.     else
  1137.     for (mcnt = lomsg; mcnt >= himsg; mcnt--)
  1138.         {
  1139.         sprintf(tmps, "%s/%s/%d", MSGBASE, conf, mcnt);
  1140.         if (msgok(tmps) <= 0)
  1141.         continue;
  1142.         if (!(*fn)(tmps, conf, mcnt))
  1143.         break;
  1144.         }
  1145.     ptr->hi_num = himsg;
  1146.     writehigh(hicnts);
  1147.     }
  1148.  
  1149. readnew()
  1150.     {
  1151.     DIR *dp;
  1152.     struct direct *dirp;
  1153.     FILE *hp;
  1154.     short himsg;
  1155.     char line[256];
  1156.  
  1157.     if ((dp = opendir(MSGBASE)) == NULL)
  1158.     {
  1159.     log("Error %d reading dir %s/", errno, MSGBASE);
  1160.     panic("msgdir");
  1161.     }
  1162.     while ((dirp = readdir(dp)) != NULL)
  1163.     {
  1164.     if (dirp->d_name[0] == '.')
  1165.         continue;
  1166.         if (isunsub(dirp->d_name))
  1167.             continue;
  1168.     printf("\nExamining conference %s...\n", dirp->d_name);
  1169.     log("Reading %s.", dirp->d_name);
  1170.     if (parms.ua_xrc && dirp->d_name[0] == 'x' && dirp->d_name[1] == '-')
  1171.         {
  1172.             if (user.u_access == A_GUEST) {
  1173.                 log("Guest skipping Restricted conference.");
  1174.                 continue;
  1175.             }
  1176.         printf("This conference is Restricted (X-RATED).  The material within may not be\nsuitable for, or acceptable to, some users.\n\nDo you wish to skip it (Y)? ");
  1177.         if (!isatty(0) || nopause)
  1178.         {
  1179.         line[0] = '\0';
  1180.         putchar('\n');
  1181.         }
  1182.         else
  1183.         gets(line);
  1184.         log("Restricted.  Skip? %s", line);
  1185.         if (ToLower(line[0]) != 'n')
  1186.         continue;
  1187.         }
  1188.     sprintf(line, "%s/%s/himsg", MSGBASE, dirp->d_name);
  1189.     if ((hp = fopen(line, "r")) == NULL)
  1190.         {
  1191.         log("Error %d opening %s", errno, line);
  1192.         puts("Can't open high message file.");
  1193.         continue;
  1194.         }
  1195.     fgets(line, 32, hp);
  1196.     fclose(hp);
  1197.     himsg = atoi(line);
  1198.     domsg(dirp->d_name, 0, himsg, doread);
  1199.     
  1200.     RN_Loop:
  1201.     printf("\nNext conference, Unsubscribe, or Stop (N): ");
  1202.     if (!isatty(0) || nopause)
  1203.         {
  1204.         putchar('\n');
  1205.         line[0] = '\0';
  1206.         }
  1207.     else
  1208.         gets(line);
  1209.     log("Next/Unsub/Stop: %s", line);
  1210.     switch (line[0])
  1211.         {
  1212.         case 'N':
  1213.         case 'n':
  1214.         case '\0':
  1215.         break;
  1216.         case 'U':
  1217.         case 'u':
  1218.             unsubscribe(dirp->d_name);
  1219.             break;
  1220.         case 'S':
  1221.         case 's':
  1222.         closedir(dp);
  1223.         return 1;
  1224.         default:
  1225.         puts("Please enter one of N, U, or S.");
  1226.         goto RN_Loop;
  1227.         }
  1228.     }
  1229.     closedir(dp);
  1230.     return 1;
  1231.     }
  1232.  
  1233. enter(s)
  1234.     char *s;
  1235.     {
  1236.     char to[256], subj[256], *p, line[256];
  1237.     short pflag;
  1238.  
  1239.     if (user.u_access == A_GUEST && strcmp(conference, "guest") != 0)
  1240.     {
  1241.     log("Security violation:  GUEST entering messages.");
  1242.     puts("You aren't allowed to enter messages in this conference.");
  1243.     return 1;
  1244.     }
  1245.     for (p = s; *p != '\0'; p++)
  1246.     if (*p == ' ')
  1247.         {
  1248.         strcpy(to, ++p);
  1249.         break;
  1250.         }
  1251.     if (*p == '\0')
  1252.     {
  1253.     printf("Who is this message to (ALL)? ");
  1254.     gets(line);
  1255.     log("To: %s", line);
  1256.     if (line[0] == '\0')
  1257.         strcpy(line, "all");
  1258.     for (p = line; *p != '\0'; p++)
  1259.         *p = ToLower(*p);
  1260.     strcpy(to, line);
  1261.     }
  1262.     printf("Subject: ");
  1263.     gets(line);
  1264.     strcpy(subj, line);
  1265.     log("Subject: %s", line);
  1266.     pflag = 0;
  1267.     if (parms.ua_pm) {
  1268.         printf("Is this message to be private (N)? ");
  1269.         gets(line);
  1270.         log("Private? %s", line);
  1271.         if (ToLower(line[0]) == 'y')
  1272.         pflag = 1;
  1273.     }
  1274.     mkmsg(to, subj, conference, pflag);
  1275.     return 1;
  1276.     }
  1277.  
  1278. reply(msg, conf)
  1279.     char *msg, *conf;
  1280.     {
  1281.     char to[256], subj[256], line[1024], rconf[256];
  1282.     short fflag, sflag, pflag;
  1283.     FILE *f;
  1284.  
  1285.     if (user.u_access == A_GUEST && strcmp(conf, "guest") != 0)
  1286.     {
  1287.     log("Security violation:  GUEST entering messages");
  1288.     puts("You aren't allowed to enter messages.");
  1289.     return;
  1290.     }
  1291.     if ((f = fopen(msg, "r")) == NULL)
  1292.     {
  1293.     log("Error %d opening %s", errno, msg);
  1294.     puts("Can't re-open message file.");
  1295.     return;
  1296.     }
  1297.     fflag = sflag = 0;
  1298.     strcpy(to, "All\n");
  1299.     strcpy(subj, "Re: Orphaned Response\n");    /* now you know... */
  1300.     while (fgets(line, 1024, f) != NULL)
  1301.     {
  1302.     if (line[0] == '\n')
  1303.         break;
  1304.     if (!fflag && strncmp(line, "From: ", 6) == 0)
  1305.         {
  1306.         strcpy(to, &line[6]);
  1307.         fflag++;
  1308.         continue;
  1309.         }
  1310.     if (!sflag && strncmp(line, "Subject: ", 9) == 0)
  1311.         {
  1312.         if (strncmp(&line[9], "Re: ", 4) == 0)
  1313.         strcpy(subj, &line[9]);
  1314.         else
  1315.         strcpy(&subj[4], &line[9]);
  1316.         sflag++;
  1317.         continue;
  1318.         }
  1319.     if (!sflag && strncmp(line, "Subject (Private): ", 19) == 0)
  1320.         {
  1321.         if (strncmp(&line[19], "Re: ", 4) == 0)
  1322.         strcpy(subj, &line[19]);
  1323.         else
  1324.         strcpy(&subj[4], &line[19]);
  1325.         sflag++;
  1326.         continue;
  1327.         }
  1328.     }
  1329.     fclose(f);
  1330.     to[strlen(to) - 1] = '\0';            /* get rid of trailing nl */
  1331.     subj[strlen(subj) - 1] = '\0';
  1332.     printf("What conference do you wish this reply to be in (%s): ", conf);
  1333.     gets(line);
  1334.     if (line[0] != '\0' && verify(line))
  1335.     {
  1336.     strcpy(rconf, line);
  1337.     conf = rconf;
  1338.     }
  1339.     pflag = 0;
  1340.     if (parms.ua_pm) {
  1341.         printf("Is this message to be private (N)? ");
  1342.         gets(line);
  1343.         log("Private? %s", line);
  1344.         if (ToLower(line[0]) == 'y')
  1345.         pflag = 1;
  1346.     }
  1347.     mkmsg(to, subj, conf, pflag);
  1348.     }
  1349.  
  1350. mkmsg(to, subj, conf, ispriv)
  1351.     char *to, *subj, *conf;
  1352.     {
  1353.     static char lockfile[] = "msgbase.lock";
  1354.     char *tempfile = mktemp("/tmp/UAmXXXXXX");
  1355.     FILE *mfp, *sfp;
  1356.     char line[1024], *p;
  1357.     long clock;
  1358.     short mcnt;
  1359.     struct tm *ltbuf;
  1360.     struct user ubuf;
  1361.  
  1362.     if (parms.ua_roc && conf[0] == 'r' && conf[1] == '-')
  1363.     {
  1364.     conf = "general";            /* responses get redirected */
  1365.     puts("Read-only conference; message will be added to \"general\".");
  1366.     }
  1367.     if (ispriv && !getuser(to, &ubuf))
  1368.     {
  1369.     printf("Can't send private message to \"%s\"; he's unregistered.\n", to);
  1370.     log("Attempted private message to unregistered user.");
  1371.     return 0;
  1372.     }
  1373.     if ((mfp = fopen(tempfile, "w")) == NULL)
  1374.     {
  1375.     log("Error %d opening %s", errno, tempfile);
  1376.     panic("tmp");
  1377.     }
  1378.     for (p = to; *p != '\0'; p++)
  1379.     *p = ToUpper(*p);
  1380.     fprintf(mfp, "To: %s\nSubject%s: %s\n\n", to, (ispriv? " (Private)": ""), subj);
  1381.     fclose(mfp);
  1382.     input(tempfile);
  1383.     for (;;)
  1384.     {
  1385.     printf("\nEdit command (L, C, E, S, or A): ");
  1386.     gets(line);
  1387.     log("Edit command: %s", line);
  1388.     switch (line[0])
  1389.         {
  1390.         case 'l':
  1391.         case 'L':
  1392.         cat(tempfile);
  1393.         break;
  1394.         case 'c':
  1395.         case 'C':
  1396.         input(tempfile);
  1397.         break;
  1398.         case 'e':
  1399.         case 'E':
  1400.         if (user.u_access == A_SYSTEM || user.u_access == A_WITNESS)
  1401.             xedit(tempfile);
  1402.         else
  1403.             edit(tempfile);
  1404.         break;
  1405.         case 'a':
  1406.         case 'A':
  1407.         printf("Do you really want to abort this edit (N)? ");
  1408.         gets(line);
  1409.         log("Abort? %s", line);
  1410.         if (ToLower(line[0]) == 'y')
  1411.             {
  1412.             unlink(tempfile);
  1413.             return 0;
  1414.             }
  1415.         break;
  1416.         case '?':
  1417.         puts("Editor commands:\nL - List message\nC - Continue message entry\nE - Edit message\nS - Save message\nA - Abort message");
  1418.         break;
  1419.         case '\0':
  1420.         break;
  1421.         case 's':
  1422.         case 'S':
  1423.         puts("Saving message...");
  1424.         mklock(lockfile);
  1425.         sprintf(line, "%s/%s/himsg", MSGBASE, conf);
  1426.         if ((sfp = fopen(line, "r")) == NULL)
  1427.             {
  1428.             log("Error %d opening %s", errno, line);
  1429.             rmlock(lockfile);
  1430.             unlink(tempfile);
  1431.             panic("himsg");
  1432.             }
  1433.         fgets(line, 32, sfp);
  1434.         fclose(sfp);
  1435.         mcnt = atoi(line) + 1;
  1436.         sprintf(line, "%s/%s/%d", MSGBASE, conf, mcnt);
  1437.         if ((sfp = fopen(line, "w")) == NULL)
  1438.             {
  1439.             log("Error %d opening %s", errno, line);
  1440.             unlink(tempfile);
  1441.             rmlock(lockfile);
  1442.             panic("msg");
  1443.             }
  1444.         fprintf(sfp, "Date: %s\nFrom: ", longdate());
  1445.         for (p = user.u_name; *p != '\0'; p++)
  1446.             putc(ToUpper(*p), sfp);
  1447.         putc('\n', sfp);
  1448.         if ((mfp = fopen(tempfile, "r")) == NULL)
  1449.             {
  1450.             fclose(sfp);
  1451.             log("Error %d opening %s", errno, tempfile);
  1452.             unlink(tempfile);
  1453.             unlink(line);
  1454.             rmlock(lockfile);
  1455.             panic("tmp");
  1456.             }
  1457.         while (fgets(line, 1024, mfp) != NULL)
  1458.             fputs(line, sfp);
  1459.         fclose(sfp);
  1460.         fclose(mfp);
  1461.         unlink(tempfile);
  1462.         sprintf(line, "%s/%s/himsg", MSGBASE, conf);
  1463.         if ((sfp = fopen(line, "w")) == NULL)
  1464.             {
  1465.             log("Error %d opening %s", errno, line);
  1466.             panic("himsg");
  1467.             }
  1468.         fprintf(sfp, "%d\n", mcnt);
  1469.         fclose(sfp);
  1470.         rmlock(lockfile);
  1471.         return 1;
  1472.         default:
  1473.         puts("Please enter L, C, E, S, or A; or ? for help.");
  1474.         }
  1475.     }
  1476.     }
  1477.  
  1478. input(file)
  1479.     char *file;
  1480.     {
  1481.     FILE *fp;
  1482.     char line[256], *p;
  1483.  
  1484.     if ((fp = fopen(file, "a")) == NULL)
  1485.     {
  1486.     log("Error %d opening %s", errno, file);
  1487.     unlink(file);
  1488.     panic("tmp");
  1489.     }
  1490.     puts("\nEnter your text now.  End it with a slash on a line by itself.\n");
  1491.     log("Entering text...");
  1492.     for (;;)
  1493.     {
  1494.     printf("] ");
  1495.     if (gets(line) == NULL)
  1496.         {
  1497.         log("Illegal character: EOF");
  1498.         clearerr(stdin);            /* 4.2 brain damage fix */
  1499.         continue;
  1500.         }
  1501.     if (strcmp(line, "/") == 0)
  1502.         break;
  1503.     for (p = line; *p != '\0'; p++)
  1504.         if (iscntrl(*p) && *p != '\t')
  1505.         {
  1506.         log("Illegal character: ^%c", uncntrl(*p));
  1507.         putc('^', fp);
  1508.         putc(uncntrl(*p), fp);
  1509.         }
  1510.         else
  1511.         putc(*p, fp);
  1512.     putc('\n', fp);
  1513.     }
  1514.     fclose(fp);
  1515.     }
  1516.  
  1517. edit(file)
  1518.     char *file;
  1519.     {
  1520.     char line[256], rline[256], *edtemp = mktemp("/tmp/UaEdXXXXXX");
  1521.     short lcnt, lnum;
  1522.     FILE *ip, *fp;
  1523.  
  1524.     for (;;)
  1525.     {
  1526.     printf("\nLine number to edit (<ENTER> to exit): ");
  1527.     gets(line);
  1528.     log("Line #: %s", line);
  1529.     if (line[0] == '\0')
  1530.         return;
  1531.     lnum = atoi(line);
  1532.     if (lnum < 1)
  1533.         continue;
  1534.     if ((fp = fopen(file, "r")) == NULL)
  1535.         {
  1536.         log("Error %d opening %s", errno, file);
  1537.         panic("tmp");
  1538.         }
  1539.     if ((ip = fopen(edtemp, "w")) == NULL)
  1540.         {
  1541.         log("Error %d opening %s", errno, edtemp);
  1542.         puts("Can't open the temporary file.");
  1543.         fclose(fp);
  1544.         return;
  1545.         }
  1546.     for (lcnt = 1; lcnt < lnum; lcnt++)
  1547.         {
  1548.         fgets(line, 256, fp);
  1549.         fputs(line, ip);
  1550.         }
  1551.     fgets(line, 256, fp);
  1552.     if (feof(fp))
  1553.         {
  1554.         puts("Not that many lines in the message.");
  1555.         fclose(fp);
  1556.         fclose(ip);
  1557.         unlink(edtemp);
  1558.         continue;
  1559.         }
  1560.     printf("\nLine %d currently reads:\n\n> %s\nRe-enter the line, or hit <ENTER> to leave it unchanged:\n\n] ", lnum, line);
  1561.     gets(rline);
  1562.     log("Replacement: %s", rline);
  1563.     if (rline[0] == '\0')
  1564.         fputs(line, ip);
  1565.     else
  1566.         fprintf(ip, "%s\n", rline);
  1567.     while (fgets(line, 256, fp) != NULL)
  1568.         fputs(line, ip);
  1569.     fclose(ip);
  1570.     fclose(fp);
  1571.     unlink(file);
  1572.     if (copylink(edtemp, file) < 0)
  1573.         {
  1574.         log("Error %d copylinking %s to %s", errno, edtemp, file);
  1575.         panic("copylink");
  1576.         }
  1577.     unlink(edtemp);
  1578.     }
  1579.     }
  1580.     
  1581. doqscan(msg, conf, mnum)
  1582.     char *msg, *conf;
  1583.     short mnum;
  1584.     {
  1585.     char line[1024];
  1586.     FILE *f;
  1587.  
  1588.     if ((f = fopen(msg, "r")) == NULL)
  1589.     {
  1590.     puts("Cannot open file.");
  1591.     log("Error %d opening %s", errno, msg);
  1592.     return 1;
  1593.     }
  1594.     printf("%5d. ", mnum);
  1595.     if (isprivate(msg))
  1596.     puts("Private message.");
  1597.     else
  1598.     while (fgets(line, 1024, f) != NULL)
  1599.         {
  1600.         if (line[0] == '\n')
  1601.         break;
  1602.         if (strncmp(line, "Subject: ", 9) == 0)
  1603.         {
  1604.         printf("%s", &line[9]);
  1605.         break;
  1606.         }
  1607.         if (strncmp(line, "Subject (Private): ", 19) == 0)
  1608.         {
  1609.         printf("%s", &line[8]);        /* include privacy tag */
  1610.         break;
  1611.         }
  1612.         }
  1613.     fclose(f);
  1614.     if (mnum % 16 == 0)    /* kludge, see comment in doscan() */
  1615.         if (!cont())
  1616.             longjmp(cmdloop, 1);
  1617.     return 1;
  1618.     }
  1619.  
  1620. qscan(s)
  1621.     char *s;
  1622.     {
  1623.     return selmsg(s, doqscan);
  1624.     }
  1625. SHAR_EOF
  1626. if test 16927 -ne "`wc -c < 'msg.c'`"
  1627. then
  1628.     echo shar: error transmitting "'msg.c'" '(should have been 16927 characters)'
  1629. fi
  1630. fi
  1631. echo shar: extracting "'param.c'" '(4415 characters)'
  1632. if test -f 'param.c'
  1633. then
  1634.     echo shar: will not over-write existing file "'param.c'"
  1635. else
  1636. cat << \SHAR_EOF > 'param.c'
  1637. /*
  1638.  * %W% %E% %U% ncoast!bsa %Z%
  1639.  * %Z% Copyright (C) 1986 by Brandon S. Allbery, All Rights Reserved %Z%
  1640.  */
  1641.  
  1642. #ifndef lint
  1643. static char _SccsId[] = "%W% %E% %U% ncoast!bsa %Z%";
  1644. static char _CopyRt[] = "%Z% Copyright (C) 1985 by Brandon S. Allbery %Z%";
  1645. #endif  lint
  1646.  
  1647. #include "ua.h"
  1648.  
  1649. struct sys parms = {
  1650.     "/usr/unaxcess",
  1651.     1,
  1652.     0,
  1653.     "ua-edit",
  1654.     "/bin/sh",
  1655.     1,
  1656.     "unaxcess",
  1657.     30,
  1658.     "sysop",
  1659.     1,
  1660.     0,
  1661.     "",
  1662.     "",
  1663.     1,
  1664.     3,
  1665.     "trap '' 2; stty -echo; echo 'Begin sending your file.  End with a CONTROL-D.'; cat - > %s; stty echo",
  1666.     "trap '' 2; cat %s",
  1667.     "umodem -rb",
  1668.     "umodem -sb",
  1669.     "kermit -iwr",
  1670.     "kermit -iws",
  1671. };
  1672.  
  1673. #define NUM        0
  1674. #define STR        1
  1675. #define BOOL        2
  1676.  
  1677. struct rparm {
  1678.     char *parmname;
  1679.     char parmtype;
  1680.     char *parmval;
  1681. } sysparms[] = {
  1682.     "readonly",    BOOL,    &parms.ua_roc,
  1683.     "x-rated",    BOOL,    &parms.ua_xrc,
  1684.     "editor",    STR,    parms.ua_edit,
  1685.     "shell",    STR,    parms.ua_shell,
  1686.     "read-env",    BOOL,    &parms.ua_env,
  1687.     "bbs-user",    STR,    parms.ua_bbs,
  1688.     "time-limit",    NUM,    &parms.ua_tlimit,
  1689.     "sysop",    STR,    parms.ua_sysop,
  1690.     "private-msgs",    BOOL,    &parms.ua_pm,
  1691.     "logging",    BOOL,    &parms.ua_log,
  1692.     "banner",    STR,    parms.ua_bnr,
  1693.     "login-msg",    STR,    parms.ua_login,
  1694.     "pauses",    NUM,    &parms.ua_hco,
  1695.     "login-tries",    NUM,    &parms.ua_nla,
  1696.     "ascii-upload",    STR,    parms.ua_auc,
  1697.     "ascii-download",STR,    parms.ua_adc,
  1698.     "xmodem-upload",STR,    parms.ua_xuc,
  1699.     "xmodem-download",STR,    parms.ua_xdc,
  1700.     "kermit-upload",STR,    parms.ua_kuc,
  1701.     "kermit-download",STR,    parms.ua_kdc,
  1702.     0,        0,    0,
  1703. };
  1704.  
  1705. /*
  1706.  * 1. Get home directory
  1707.  * 2. Open $HOME/uaconfig
  1708.  * 3. Parse lines; # is a comment, input form is KEYWORD VALUE
  1709.  *    VALUE is numeric, Y/N, "string" and backslash escapes for
  1710.  *     \n \t \r \b \f \e \nnn are understood
  1711.  * 4. Assign the values to the parms structure
  1712.  */
  1713.  
  1714. static char line[512], var[20], sval[50];
  1715.  
  1716. getparms() {
  1717.      char home[512];
  1718.      FILE *cfp;
  1719.      short nval, cnt, pos, scnt, canon;
  1720.      
  1721. #ifdef JPNHACK
  1722.      strcpy(home, "/c/jpn/ua");
  1723. #else
  1724.      strcpy(home, getpwuid(geteuid())->pw_dir);
  1725. #endif
  1726.      strcpy(parms.ua_home, home);
  1727.      strcpy(line, home);
  1728.      strcat(line, "/");
  1729.      strcat(line, CONFIG);
  1730.      if ((cfp = fopen(line, "r")) == NULL) {
  1731.          fprintf(stderr, "panic: param get, %s\n", line);
  1732.          exit(1);
  1733.      }
  1734.      while (fgets(line, 512, cfp) != NULL) {
  1735.          line[strlen(line) - 1] = '\0';
  1736.          if (Index(line, '#') != NULL)
  1737.              *(Index(line, '#')) = '\0';
  1738.          scnt = 0;
  1739.          pos = 0;
  1740.          while (line[pos] != '\0' && line[pos] != ' ' && line[pos] != '\t')
  1741.              var[scnt++] = line[pos++];
  1742.          var[scnt] = '\0';
  1743.          if (var[0] == '\0')
  1744.              continue;
  1745.          for (cnt = 0; sysparms[cnt].parmname != NULL; cnt++)
  1746.              if (strcmp(sysparms[cnt].parmname, var) == 0)
  1747.                  break;
  1748.          if (sysparms[cnt].parmname == NULL) {
  1749.              fprintf(stderr, "Please inform the sysop that there is an invalid parameter\nin the setup file.\n");
  1750.              continue;
  1751.          }
  1752.         while (line[pos] == ' ' || line[pos] == '\t')
  1753.             pos++;
  1754.          switch (sysparms[cnt].parmtype) {
  1755.              case NUM:
  1756.                  *((char *) sysparms[cnt].parmval) = atoi(&line[pos]) & 0xff;
  1757.                  break;
  1758.              case BOOL:
  1759.                  if (line[pos] == '\0' || ToLower(line[pos]) == 'y')
  1760.                      *((char *) sysparms[cnt].parmval) = 1;
  1761.                  else
  1762.                      *((char *) sysparms[cnt].parmval) = 0;
  1763.                  break;
  1764.              case STR:
  1765.                  if (line[pos] == '"') {
  1766.                      canon = 1;
  1767.                      pos++;
  1768.                  }
  1769.                  for (scnt = 0; (canon? line[pos] != '"': line[pos] != '\0' && line[pos] != ' ' && line[pos] != '\t'); pos++, scnt++) {    
  1770.                      if (canon && line[pos] == '\\') {
  1771.                          switch (line[++pos]) {    
  1772.                              case 'n':
  1773.                                  sval[scnt] = '\n';
  1774.                                  break;
  1775.                              case 't':
  1776.                                  sval[scnt] = '\t';
  1777.                                  break;
  1778.                              case 'r':
  1779.                                  sval[scnt] = '\r';
  1780.                                  break;
  1781.                              case 'b':
  1782.                                  sval[scnt] = '\b';
  1783.                                  break;
  1784.                              case 'f':
  1785.                                  sval[scnt] = '\f';
  1786.                                  break;
  1787.                              case 'e':
  1788.                              case 'E':
  1789.                                  sval[scnt] = '\033';
  1790.                                  break;
  1791.                              case 'a':
  1792.                                  sval[scnt] = '\7';    /* proposed extension of C string metasyntax */
  1793.                                  break;
  1794.                              case '0':
  1795.                              case '1':
  1796.                              case '2':
  1797.                              case '3':
  1798.                              case '4':
  1799.                              case '5':
  1800.                              case '6':
  1801.                              case '7':
  1802.                                  sval[scnt] = 0;
  1803.                                  while (Index("01234567", line[pos]) != NULL)
  1804.                                      sval[scnt] = sval[scnt] * 8 + (line[pos++] - '0');
  1805.                                 pos--;
  1806.                                 break;
  1807.                             default:
  1808.                                 sval[scnt] = line[pos];
  1809.                          }
  1810.                      }
  1811.                      else
  1812.                          sval[scnt] = line[pos];
  1813.                  }
  1814.                  sval[scnt] = '\0';
  1815.                  strcpy(sysparms[cnt].parmval, sval);
  1816.          }
  1817.      }
  1818. }
  1819. SHAR_EOF
  1820. if test 4415 -ne "`wc -c < 'param.c'`"
  1821. then
  1822.     echo shar: error transmitting "'param.c'" '(should have been 4415 characters)'
  1823. fi
  1824. fi
  1825. echo shar: extracting "'sys.c'" '(8173 characters)'
  1826. if test -f 'sys.c'
  1827. then
  1828.     echo shar: will not over-write existing file "'sys.c'"
  1829. else
  1830. cat << \SHAR_EOF > 'sys.c'
  1831. /*
  1832.  * %W% %E% %U% ncoast!bsa %Z%
  1833.  * %Z% Copyright (C) 1986 by Brandon S. Allbery, All Rights Reserved %Z%
  1834.  */
  1835.  
  1836. #ifndef lint
  1837. static char _SccsId[] = "%W% %E% %U% ncoast!bsa %Z%";
  1838. static char _CopyRt[] = "%Z% Copyright (C) 1985 by Brandon S. Allbery %Z%";
  1839. #endif  lint
  1840.  
  1841. #include "ua.h"
  1842.  
  1843. static FILE *lfp;
  1844.  
  1845. short critical = 0;
  1846.  
  1847. short quitc = 0;
  1848. short intr = 0;
  1849. short alrm = 0;
  1850.  
  1851. short shhh = 0;
  1852.  
  1853. short warned = 0;
  1854.  
  1855. #ifdef SYS3
  1856. #include <sys/ioctl.h>
  1857. #include <termio.h>
  1858. struct termio mode;
  1859. #else
  1860. #include <sgtty.h>
  1861. #ifndef V7
  1862. #include <sys/ioctl.h>
  1863. #endif
  1864. struct sgttyb mode;
  1865. #endif
  1866.  
  1867. logon()
  1868.     {
  1869.     struct stat sb;
  1870.     char *cp;
  1871.     char *getenv();
  1872.  
  1873.         /* first set up ttymode structure */
  1874. #ifdef SYS3
  1875.     ioctl(0, TCGETA, &mode);
  1876. #else
  1877. #ifdef V7
  1878.     gtty(0, &mode);
  1879. #else
  1880.     ioctl(0, TIOCGETP, &mode);
  1881. #endif
  1882. #endif
  1883.  
  1884.     if (parms.ua_env) {
  1885.         if ((cp = getenv("SHELL")) != NULL)
  1886.             strcpy(parms.ua_shell, cp);
  1887.         if ((cp = getenv("EDITOR")) != NULL)
  1888.             strcpy(parms.ua_edit, cp);
  1889.     }
  1890.     
  1891.     if (!parms.ua_log || stat(LOG, &sb) < 0)        /* no logfile => no logging */
  1892.     {
  1893.     lfp = NULL;
  1894.     return;
  1895.     }
  1896.     if ((lfp = fopen(LOG, "a")) == NULL)
  1897.     {
  1898.     perror(LOG);
  1899.     puts("panic: log");
  1900.     exit(2);
  1901.     }
  1902.     }
  1903.  
  1904. log(fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
  1905.     char *fmt, *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8, *a9;
  1906.     {
  1907.     char buf[1024];
  1908.     static char lockfile[] = "logfile.lock";
  1909.  
  1910.     if (lfp == NULL)            /* logging not enabled */
  1911.     return;
  1912.     CRIT();
  1913.     sprintf(buf, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
  1914.     mklock(lockfile);
  1915.     fprintf(lfp, "%s (%05d)  %s\n", date(), getpid(), visible(buf));
  1916.     fflush(lfp);
  1917.     rmlock(lockfile);
  1918.     NOCRIT();
  1919.     }
  1920.  
  1921. logsig(sig)
  1922.     int sig;
  1923.     {
  1924.     log("Received signal %d.", sig);
  1925.     panic("signal");
  1926.     }
  1927.  
  1928. panic(s)
  1929.     char *s;
  1930.     {
  1931.     log("panic: %s", s);
  1932.     fprintf(stderr, "panic: %s\n", s);
  1933.     unlink(RIndex(ttyname(2), '/') + 1);
  1934.     exit(1);
  1935.     }
  1936.  
  1937. quit()
  1938.     {
  1939.     char line[256];
  1940.  
  1941.     if (critical) {
  1942.         quitc++;
  1943.         return;
  1944.     }
  1945.     puts("\n\nFast logout\n");
  1946.     signal(SIGQUIT, quit);
  1947.     log("Signalled QUIT.");
  1948.     printf("\nDo you really want to leave UNaXcess (N)? ");
  1949.     gets(line);
  1950.     if (ToLower(line[0]) == 'y')
  1951.     {
  1952.     printf("OK, %s.  See you later!\n\n\n", user.u_name);
  1953.     cleanup();
  1954.     }
  1955.     }
  1956.  
  1957. intrp()
  1958.     {
  1959.     if (critical) {
  1960.         intr++;
  1961.         return;
  1962.     }
  1963.     puts("\n\nAborted.");
  1964.     log("Command aborted.");
  1965.     signal(SIGINT, intrp);
  1966.     longjmp(cmdloop, 1);
  1967.     }
  1968.  
  1969. char *visible(s)
  1970.     char *s;
  1971.     {
  1972.     static char vs[256];
  1973.     char *sp, *vp;
  1974.  
  1975.     vp = vs;
  1976.     for (sp = s; *sp != '\0'; sp++)
  1977.     if (!iscntrl(*sp))
  1978.         *vp++ = *sp;
  1979.     else
  1980.         {
  1981.         *vp++ = '^';
  1982.         *vp++ = uncntrl(*sp);
  1983.         }
  1984.     *vp = '\0';
  1985.     return vs;
  1986.     }
  1987.  
  1988. shell()
  1989.     {
  1990.     short sig;
  1991.     unsigned altime;
  1992.  
  1993.     if (user.u_access == A_GUEST || user.u_access == A_USER || parms.ua_shell[0] == '\0')
  1994.     {
  1995.     puts("You don't have shell access privileges.");
  1996.     log("Security violation:  Unauthorized SHELL");
  1997.     return 1;
  1998.     }
  1999.     switch (fork())
  2000.     {
  2001.     case -1:
  2002.         log("Error %d forking shell", errno);
  2003.         puts("Sorry, the system's full.  Try again later.");
  2004.         return 1;
  2005.     case 0:
  2006.         for (sig = 2; sig < SIGUSR1; sig++)
  2007.         signal(sig, SIG_DFL);
  2008.         setuid(getuid());
  2009.         chdir(getpwuid(getuid())->pw_dir);
  2010.         run(parms.ua_shell, 0);
  2011.         log("Error %d exec'ing %s", errno, parms.ua_shell);
  2012.         puts("Couldn't run the shell.");
  2013.         exit(1);
  2014.     default:
  2015.         CRIT();
  2016.         for (sig = 2; sig < SIGUSR1; sig++)
  2017.         signal(sig, SIG_IGN);
  2018.         signal(SIGALRM, thatsall);    /* trapped by the CRIT() */
  2019.         wait(NULL);
  2020.         signal(SIGINT, intrp);
  2021.         signal(SIGQUIT, quit);
  2022.         for (sig = 4; sig < SIGUSR1; sig++)
  2023.         signal(sig, logsig);
  2024.         signal(SIGALRM, thatsall);
  2025.         NOCRIT();
  2026.     }
  2027.     return 1;
  2028.     }
  2029.  
  2030. thatsall()
  2031.     {
  2032.     if (critical) {
  2033.         alrm++;
  2034.         return;
  2035.     }
  2036.     if (warned) {
  2037.         log("Timeout.");
  2038.         puts("\nI'm sorry, but you're out of time.\n\n");
  2039.         cleanup();
  2040.         }
  2041.     else 
  2042.         {
  2043.         log("5-minute warning.");
  2044.         puts("\nYou have only five minutes left in this session.\n\n");
  2045.         warned = 1;
  2046.         alarm(5 * 60);
  2047.         }
  2048.     }
  2049.  
  2050. /*
  2051.  * I've had problems with this.  If it breaks, delete the innards of the lock
  2052.  * functions.  Hopefully, I got it right this time...
  2053.  */
  2054.  
  2055. mklock(lockfile)
  2056. char *lockfile; {
  2057.     char lockpath[50];
  2058.     int lock_fd;
  2059.     struct stat statbuf;
  2060.     
  2061. /*  strcpy(lockpath, "lock/"); */  /* jpn - install did not create lock/ */
  2062.     strcpy(lockpath, lockfile);
  2063.     while (stat(lockpath, &statbuf) == 0)
  2064.         if (statbuf.st_atime > 60) {
  2065.             unlink(lockpath);
  2066.             break;
  2067.         }
  2068.     if ((lock_fd = creat(lockpath, 0600)) < 0) {
  2069.         fprintf(stderr, "Errno = %d creating lockfile %s\n", errno, lockpath);
  2070.         exit(-1);
  2071.     }
  2072.     close(lock_fd);
  2073. }
  2074.  
  2075. rmlock(lockfile)
  2076. char *lockfile; {
  2077.     char lockpath[50];
  2078.     struct stat statbuf;
  2079.     
  2080. /*  strcpy(lockpath, "lock/"); */  /* jpn - install did not create lock/ */
  2081.     strcpy(lockpath, lockfile);
  2082.     if (stat(lockpath, &statbuf) < 0) {
  2083.         log("Lockfile %s deleted???", lockpath);
  2084.         printf("\n\nSomeone futzed with the lockfile.  Please tell %s IMMEDIATELY!!!\nSorry, but this means I have to log you out now.\n\n", parms.ua_sysop);
  2085.         panic("LOCKFILE DELETED");
  2086.     }
  2087.     if (unlink(lockpath) < 0) {
  2088.         log("Errno = %d, can't unlink lockfile %s", errno, lockpath);
  2089.         puts("\nI've got a lockfile problem.  You won't be able to do some\nthings until it's fixed.  Sorry...\n");
  2090.     }
  2091. }
  2092.  
  2093. xedit(file)
  2094.     char *file;
  2095.     {
  2096.     short sig;
  2097.     unsigned altime;
  2098.  
  2099.     if (user.u_access == A_GUEST || user.u_access == A_USER || parms.ua_edit[0] == '\0')
  2100.     {
  2101.     puts("You don't have shell access privileges.");
  2102.     log("Security violation:  Unauthorized XEDIT");
  2103.     return 1;
  2104.     }
  2105.     if (strcmp(parms.ua_edit, "ua-edit") == 0) {
  2106.         edit(file);
  2107.         return 1;
  2108.     }
  2109.     switch (fork())
  2110.     {
  2111.     case -1:
  2112.         log("Error %d forking shell", errno);
  2113.         puts("Sorry, the system's full.  Using the line editor...");
  2114.         edit(file);
  2115.         return 1;
  2116.     case 0:
  2117.         for (sig = 2; sig < SIGUSR1; sig++)
  2118.         signal(sig, SIG_DFL);
  2119.         setuid(getuid());
  2120.         chdir(getpwuid(getuid())->pw_dir);
  2121.         run(parms.ua_edit, file);
  2122.         log("Error %d exec'ing %s", errno, parms.ua_edit);
  2123.         puts("Couldn't run the editor; using the line editor...");
  2124.         edit(file);
  2125.         exit(0);
  2126.     default:
  2127.         CRIT();
  2128.         for (sig = 2; sig < SIGUSR1; sig++)
  2129.         signal(sig, SIG_IGN);
  2130.         signal(SIGALRM, thatsall);
  2131.         wait(NULL);
  2132.         signal(SIGINT, intrp);
  2133.         signal(SIGQUIT, quit);
  2134.         for (sig = 4; sig < SIGUSR1; sig++)
  2135.         signal(sig, logsig);
  2136.         signal(SIGALRM, thatsall);
  2137.         NOCRIT();
  2138.     }
  2139.     return 1;
  2140.     }
  2141.  
  2142. CRIT() {
  2143.     alrm = 0;
  2144.     quitc = 0;
  2145.     intr = 0;
  2146.     if (critical)
  2147.         return;    /* clears pending signals */
  2148.     critical = 1;
  2149. }
  2150.  
  2151. NOCRIT() {
  2152.     if (!critical)
  2153.         return;
  2154.     critical = 0;
  2155.     if (alrm)
  2156.         thatsall(14);
  2157.     if (quitc)
  2158.         quit(3);
  2159.     if (intr)
  2160.         intrp(2);
  2161.     alrm = 0;
  2162.     quitc = 0;
  2163.     intr = 0;
  2164. }
  2165.  
  2166. run(cmd, arg)
  2167. char *cmd, *arg; {
  2168.     char cmdbuf[5120];
  2169.     
  2170.     sprintf(cmdbuf, "%s %s", cmd, (arg? arg: ""));
  2171.     execl("/bin/sh", "sh", "-c", cmdbuf, 0);
  2172.     return -1;
  2173. }
  2174.  
  2175. silent() {
  2176.     if (shhh)
  2177.         return;
  2178. #ifdef SYS3
  2179.     mode.c_lflag &= ~(ICANON|ISIG|ECHO|ECHOE|ECHOK);
  2180.     mode.c_cc[VMIN] = 1;
  2181.     mode.c_cc[VTIME] = 0;
  2182.     ioctl(0, TCSETAW, &mode);
  2183. #else
  2184.     mode.sg_flags |= CBREAK;
  2185.     mode.sg_flags &= ~ECHO;
  2186. #ifdef V7
  2187.     stty(0, &mode);
  2188. #else
  2189.     ioctl(0, TIOCSETP, &mode);
  2190. #endif
  2191. #endif
  2192.     shhh = 1;
  2193. }
  2194.  
  2195. talk() {
  2196.     if (!shhh)
  2197.         return;
  2198. #ifdef SYS3
  2199.     mode.c_lflag |= (ICANON|ISIG|ECHO|ECHOE|ECHOK);
  2200.     mode.c_cc[VEOF] = CEOF;
  2201.     mode.c_cc[VEOL] = CNUL;
  2202.     ioctl(0, TCSETAW, &mode);
  2203. #else
  2204.     mode.sg_flags |= ECHO;
  2205.     mode.sg_flags &= ~CBREAK;
  2206. #ifdef V7
  2207.     stty(0, &mode);
  2208. #else
  2209.     ioctl(0, TIOCSETP, &mode);
  2210. #endif
  2211. #endif
  2212.     shhh = 0;
  2213. }
  2214.  
  2215. copylink(src, dest)
  2216. char *src, *dest; {
  2217.     int srcp, destp, cnt;
  2218.     char buf[1024];
  2219.     
  2220.     if (link(src, dest) == 0) {
  2221.         unlink(src);
  2222.         return 0;
  2223.     }
  2224.     if ((srcp = open(src, 0)) < 0) {
  2225.         perror(src);
  2226.         return -1;
  2227.     }
  2228.     unlink(dest);
  2229.     if ((destp = creat(dest, 0600)) < 0) {
  2230.         perror(dest);
  2231.         return -1;
  2232.     }
  2233.     while ((cnt = read(srcp, buf, sizeof buf)) > 0)
  2234.         write(destp, buf, cnt);
  2235.     close(destp);
  2236.     close(srcp);
  2237.     return 0;
  2238. }
  2239. SHAR_EOF
  2240. if test 8173 -ne "`wc -c < 'sys.c'`"
  2241. then
  2242.     echo shar: error transmitting "'sys.c'" '(should have been 8173 characters)'
  2243. fi
  2244. fi
  2245. exit 0
  2246. #    End of shell archive
  2247.